/*
 *                  BioJava development code
 *
 * This code may be freely distributed and modified under the
 * terms of the GNU Lesser General Public Licence.  This should
 * be distributed with the code.  If you do not have a copy,
 * see:
 *
 *      http://www.gnu.org/copyleft/lesser.html
 *
 * Copyright for this code is held jointly by the individual
 * authors.  These should be listed in @author doc comments.
 *
 * For more information on the BioJava project and its aims,
 * or to join the biojava-l mailing list, visit the home page
 * at:
 *
 *      http://www.biojava.org/
 * 
 * Created on Jun 22, 2007
 * 
 */

package org.biojava.services.das.registry;

import java.awt.Image;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import javax.swing.ImageIcon;

import org.biojava.dasobert.dasregistry.DasSource;
import org.biojava.services.das.dao.DasSourceManager;
import org.biojava.services.das.dao.DasUserDAO;
import org.biojava.services.das.dao.ProjectBean;
import org.biojava.services.das.dao.RegistryUser;
import org.biojava.services.das.dao.Role;
import org.biojava.services.das.dao.UserDAO;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;


/** a manager to take care of RegistryUser and ProjectBean DB access
 * 
 * @author Andreas Prlic
 *
 */
public class UserManager implements Serializable {

	
	DataSource dataSource;
	DasUserDAO dao;
	/**
	 * 
	 */
	private static final long serialVersionUID = 6153607450420341752L;
	public static Logger logger =  Logger.getLogger("org.biojava.services.das.registry");

	public DataSource getDataSource() {
		return dataSource;
	}

	public void setDataSource(DataSource dataSource) {
		this.dataSource = dataSource;
	}


	public DasUserDAO getDao() {
		return dao;
	}

	public void setDao(DasUserDAO dao) {
		this.dao = dao;
	}



	Pattern emailPattern;


	public UserManager() {
		

		emailPattern = Pattern.compile("^[A-Za-z0-9\\._%-]+@[A-Za-z0-9\\._%-]+\\.[A-Za-z]{2,4}$");
	}

	/** check if a DAS source is owned by a user
	 * 
	 * @param user
	 * @param auto_id
	 * @return flag;
	 */
	public boolean isOwner(RegistryUser user, int auto_id){
		boolean isOwner = false;
		Connection conn = null ;
		if(user==null){
			return false;
		}
		try {

			conn = dataSource.getConnection() ;

			isOwner = dao.isOwner(conn,user,auto_id);

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if ( conn != null){
				try {
					conn.close();
				} catch (SQLException ex){
					ex.printStackTrace();
				}
			}
		}
		return isOwner;
	}


	public RegistryUser[] getAllUsers(){
		Connection conn = null ;
		RegistryUser[] owners = new RegistryUser[0];
		try {

			conn = dataSource.getConnection() ;

			owners = dao.getAllUsers(conn);

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if ( conn != null){
				try {
					conn.close();
				} catch (SQLException ex){
					ex.printStackTrace();
				}
			}
		}
		return owners;
	}

	public RegistryUser[] getOwners(int auto_id){
		Connection conn = null ;
		RegistryUser[] owners = new RegistryUser[0];
		try {

			conn = dataSource.getConnection() ;


			owners = dao.getOwners(conn,auto_id);
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if ( conn != null){
				try {
					conn.close();
				} catch (SQLException ex){
					ex.printStackTrace();
				}
			}
		}
		return owners;
	}



	public boolean isValidEmail(String email){
		Matcher m = emailPattern.matcher(email);	
		return m.matches() ;
	}

	/** check if the provided OpenID is already in database
	 * 
	 * @param openid
	 * @return flag 
	 */
	public boolean isNewUser(String openid){
		boolean isNew = true;
			isNew = dao.isNewUser(openid);

		return isNew;
	}

	public RegistryUser getUserById(int user_id){
		RegistryUser u = null;
		Connection conn = null ;	
		try {

			conn = dataSource.getConnection() ;

			u = dao.getUserById(conn, user_id);

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if ( conn != null){
				try {
					conn.close();
				} catch (SQLException ex){
					ex.printStackTrace();
				}
			}
		}

		return u;
	}

	public RegistryUser getUser(String email){

		
		RegistryUser u=dao.getUser(email);
		//Connection conn = null ;	
//		try {
//
//			conn = dataSource.getConnection() ;
//
//			u = dao.getUser(openid);
//
//		} catch (SQLException e) {
//			e.printStackTrace();
//		} finally {
//			if ( conn != null){
//				try {
//					conn.close();
//				} catch (SQLException ex){
//					ex.printStackTrace();
//				}
//			}
//		}

		return u;

	}


	/** create a new user and return the user_id
	 * 
	 * @param user
	 * @return the user_id of the newly created user
	 */
	public int createNewUser(RegistryUser user){
		int user_id = -1;

		Connection conn = null ;	
		try {

			
			user_id = dao.storeUser( user);
			conn = dataSource.getConnection() ;

			dao.linkDasSourcesToUser(conn,user);

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if ( conn != null){
				try {
					conn.close();
				} catch (SQLException ex){
					ex.printStackTrace();
				}
			}
		}
		return user_id;
	}



	public void addDasSource2Owner(int auto_id){
		if ( auto_id < 0)
			return;
		
		Connection conn = null ;	
		try {

			conn = dataSource.getConnection() ;

			dao.addDasSource2Owner(conn, auto_id);

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if ( conn != null){
				try {
					conn.close();
				} catch (SQLException ex){
					ex.printStackTrace();
				}
			}
		}
		
	}
	
	public void addOwner(RegistryUser user, int auto_id, boolean updateEmail){
		
		if (auto_id < 1)
			return;
		
		Connection conn = null ;	
		try {

			conn = dataSource.getConnection() ;

			dao.addOwner(conn,user,auto_id, false);

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if ( conn != null){
				try {
					conn.close();
				} catch (SQLException ex){
					ex.printStackTrace();
				}
			}
		}

	}
	
public void addOwner(RegistryUser user, int auto_id){
		
		if (auto_id < 1)
			return;
		
		Connection conn = null ;	
		try {

			conn = dataSource.getConnection() ;

			dao.addOwner(conn,user,auto_id);

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if ( conn != null){
				try {
					conn.close();
				} catch (SQLException ex){
					ex.printStackTrace();
				}
			}
		}

	}

	public void removeOwner(RegistryUser user, int auto_id){
		Connection conn = null ;	
		try {

			conn = dataSource.getConnection() ;

			dao.removeOwner(conn,user,auto_id);

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if ( conn != null){
				try {
					conn.close();
				} catch (SQLException ex){
					ex.printStackTrace();
				}
			}
		}

	}

	public void updateUser(RegistryUser user){
		Connection conn = null ;	
		try {

			conn = dataSource.getConnection() ;
			dao.updateUser(conn, user);
			dao.linkDasSourcesToUser(conn,user);
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if ( conn != null){
				try {
					conn.close();
				} catch (SQLException ex){
					ex.printStackTrace();
				}
			}
		}
	}


	public void deleteUser(RegistryUser user){
		
			
			dao.deleteUser(user.getUserID());
		
		
	}

	public void deleteProject(ProjectBean project){
		Connection conn = null ;

		try {

			conn = dataSource.getConnection() ;
			dao.deleteProject(conn,project);			
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if ( conn != null){
				try {
					conn.close();
				} catch (SQLException ex){
					ex.printStackTrace();
				}
			}
		}
	}

	public void addDasSource2Project(ProjectBean project, int auto_id){

		Connection conn = null ;	
		try {

			conn = dataSource.getConnection() ;

			dao.addDasSource2Project(conn,project,auto_id);

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if ( conn != null){
				try {
					conn.close();
				} catch (SQLException ex){
					ex.printStackTrace();
				}
			}
		}

	}

	public void removeDasSourceFromProject( int auto_id){

		Connection conn = null ;	
		try {

			conn = dataSource.getConnection() ;

			dao.removeDasSourceFromProject(conn,auto_id);

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if ( conn != null){
				try {
					conn.close();
				} catch (SQLException ex){
					ex.printStackTrace();
				}
			}
		}

	}

	/** remove server
	 * an int is returned, wich provides the status of the request:
	 *  1: successfully removed
	 *  2:  user doe nothave permission to remove this service ;
	 *  0: some other error occured;
	 * @param serverurl 
	 * @param owner the user that is owner of this DAS source 
	 * @return the status of the request 
	 */

	public int removeService(String serverurl, RegistryUser owner) {
		
		BeanFactory ctx=(new ClassPathXmlApplicationContext("SpringDAO.xml"));
		DasRegistrySql registry=(DasRegistrySql)ctx.getBean("registryBean");
		DasSource ds = registry.getDasSourceByURL(serverurl);
		int auto_id = registry.getAutoID4DasSource(ds);
		
		boolean license2kill = false;
		
		if ( isOwner(owner, auto_id)){
			license2kill = true;
		}
		
		if ( Role.isAdmin(owner)){
			license2kill = true;
		}
		
		if ( ! license2kill)
			return 2;
	
		// ok. we have permission to delete this one
		
			//DasSourceManager dsman=(DasSourceManager) ctx.getBean("dasSourceManager");
			//dsman.removeLocalSource(auto_id);
			dao.removeDasSource(serverurl);
		
		
		
		return 1;
	}



	public int createProject(ProjectBean project,int user_id){
		Connection conn = null ;
		int id = -1;
		try {

			conn = dataSource.getConnection() ;
			id = dao.createProject(conn,project,user_id);
			project.setProjectID(id);
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if ( conn != null){
				try {
					conn.close();
				} catch (SQLException ex){
					ex.printStackTrace();
				}
			}
		}

		return id;
	}

	public void updateProject(ProjectBean project){
		Connection conn = null ;

		try {

			conn = dataSource.getConnection() ;
			dao.updateProject(conn,project);

		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if ( conn != null){
				try {
					conn.close();
				} catch (SQLException ex){
					ex.printStackTrace();
				}
			}
		}
	}

	public void writeProjectImage(ProjectBean p , Image image, String imageFormat){
		System.out.println("usermanger writing project image " + imageFormat);
		Connection conn = null ;	
		try {

			conn = dataSource.getConnection() ;

			dao.writeProjectImage(conn, p, image,imageFormat);

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if ( conn != null){
				try {
					conn.close();
				} catch (SQLException ex){
					ex.printStackTrace();
				}
			}
		}


	}

	public ImageIcon getProjectImage(ProjectBean p){

		if (p==null)
			return null;

		Connection conn = null ;
		ImageIcon icon = null;
		try {

			conn = dataSource.getConnection() ;

			icon = dao.getImageForProject(conn, p);

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if ( conn != null){
				try {
					conn.close();
				} catch (SQLException ex){
					ex.printStackTrace();
				}
			}
		}

		return icon;


	}



	public ProjectBean getProjectById(int project_id){
		Connection conn = null ;
		ProjectBean p = null;

		try {

			conn = dataSource.getConnection() ;

			p = dao.getProjectForId(conn, project_id);

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if ( conn != null){
				try {
					conn.close();
				} catch (SQLException ex){
					ex.printStackTrace();
				}
			}
		}

		return p;


	}
	
	

	/*public void simple(){
		Connection conn = null ;	
		try {

			conn = dataSource.getConnection() ;
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if ( conn != null){
				try {
					conn.close();
				} catch (SQLException ex){
					ex.printStackTrace();
				}
			}
		}


	}*/


}
